1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
---
import Layout from "../../layouts/Layout.astro";
import { getCollection, render } from "astro:content";
import { type GetStaticPaths } from "astro";
interface Props {
entry: any;
}
export const getStaticPaths: GetStaticPaths = async () => {
const entries = await getCollection("blog");
return entries.map((entry: any) => ({
params: { id: entry.id },
props: { entry },
}));
};
const { entry } = Astro.props;
const { Content } = await render(entry);
const formattedDate = new Date(entry.data.publishedAt).toLocaleDateString(
"es-ES",
{
year: "numeric",
month: "long",
day: "numeric",
weekday: "long",
},
);
const schema = {
"@context": "https://schema.org",
"@type": "BlogPosting",
headline: entry.data.title,
datePublished: entry.data.publishedAt.toISOString(),
author: {
"@type": "Person",
name: "Ariel Costas Guerrero",
},
publisher: {
"@type": "Person",
name: "Ariel Costas Guerrero",
logo: {
"@type": "ImageObject",
url: "https://www.costas.dev/favicon.png",
},
},
};
---
<Layout title={entry.data.title} description={entry.data.metaDescription}>
<script
is:inline
type="application/ld+json"
slot="head-jsonld"
set:html={JSON.stringify(schema)}
/>
<h1>{entry.data.title}</h1>
<small>
Publicado el
<time datetime={entry.data.publishedAt.toISOString()}>
{formattedDate}
</time>
{entry.data.tags && entry.data.tags.length > 0 && (
<>
• Etiquetas:
<ul class="tags">
{entry.data.tags.map((tag: string) => (
<li><a href={`/blog/?tag=${encodeURIComponent(tag)}`}>{tag}</a></li>
))}
</ul>
</>
)}
</small>
<Content />
</Layout>
<style lang="scss">
@use "../../../styles/variables" as v;
@use "sass:color";
.tags {
display: inline-flex;
list-style: none;
margin: 0;
padding: 0;
gap: 0.75rem;
}
.tags li {
display: inline;
}
.tags a {
// Estilo de enlace normal, siguiendo los estilos predefinidos en Layout.astro
color: v.$accentDark;
font-size: 0.85rem;
font-family: v.$monoFontStack;
text-decoration: none;
box-shadow: 0 1px v.$accent;
transition: all 0.2s ease;
&:hover {
box-shadow: 0 2px v.$accentDark;
}
&:focus {
color: v.$accentDark;
outline: none;
background-color: v.$secondary;
box-shadow: 0 4px #0b0c0c;
}
}
/* Estilos para la información de la publicación */
small {
display: block;
margin-top: -1rem;
margin-bottom: 1.5rem;
font-size: 0.85rem;
color: color.adjust(v.$dark, $lightness: 30%);
}
time {
font-style: italic;
}
</style>
|